<?php

// vendor\illuminate\support\helpers.php

use Illuminate\Support\Arr;
use Illuminate\Support\Debug\Dumper;
use Dingo\Api\Exception\ValidationHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;

if (!function_exists('error')) {
    /**
     * 抛出 HTTP 异常
     * 
     * @param  string       $type      异常类型
     * @param  string|array $message   自定义消息
     * @param  int          $errorCode 特殊错误码
     * @param  array        $headers   头信息
     * @param  array        $errors    可能的错误信息数组
     * @return void
     */
    function error(string $type, $message = '', int $errorCode = null, array $headers = [], array $errors = null)
    {
        $httpStatusCode = [
            'create_fail'     => 400,
            'update_fail'     => 400,
            'delete_fail'     => 400,
            'unauthorized'    => 401, // 表示用户没有权限（令牌、用户名、密码错误）
            'forbidden'       => 403, // 表示用户得到授权（与401错误相对），但是访问是被禁止的
            'not_found'       => 404,
            'validation_fail' => 422, // 验证错误
            'sql_fail'        => 500, // 数据库相关错误
        ][$type];

        // 复杂的多参数校验错误
        if ($httpStatusCode === 422 && is_array($message)) {

            // $errors = $message;
            $message = reset($message)[0];

        }

        $code = $errorCode;
        throw new \Api\HttpException($httpStatusCode, $message, $headers, $code, $errors);
    }
}

if (! function_exists('success')) {
    /**
     * 构造并返回请求成功的资源响应
     *
     * @param  array  $data    资源数组
     * @param  array  $headers 头信息
     * @return void
     */
    function success(array $data = null, array $headers = [])
    {
        $list = [];
        $httpStatusCode = $code = 200;
        // 分页列表
        if (isset($data['current_page'])) {
            foreach ($data['data'] as $index => $item) {
                foreach ($item as $key => $value) {
                    $list[$index][camel_case($key)] = $value;
                }
            }
            $resource = [
                'total' => $data['total'],
                'list' => $list,
                'perPage' => $data['per_page'],
                'currentPage' => $data['current_page'],
            ];
        } else if (isset($data[0])) {
            foreach ($data as $index => $item) {
                foreach ($item as $key => $value) {
                    $list[$index][camel_case($key)] = $value;
                }
            }
            $resource = [
                'total' => count($data),
                'list' => $list,
            ];
        }
        // 常规资源
        else {
            if ($data === null) {
                $resource = (object) null;
            } else {
                foreach ($data as $key => $value) {
                    if ($value && is_array($value)) {
                        foreach ($value as $index => $item) {
                            if (is_array($item)) {
                                foreach ($item as $k => $v) {
                                    $resource[camel_case($key)][camel_case($index)][camel_case($k)] = $v;
                                }
                            } else {
                                $resource[camel_case($key)][camel_case($index)] = $item;
                            }
                        }
                    } else {
                        $resource[camel_case($key)] = $value;
                    }
                }
            }
        }

        $content = compact('code', 'resource');
        response($content, $httpStatusCode, $headers)->throwResponse();
    }
}

if (!function_exists('_error')) {
    /**
     * 抛出 HTTP 异常
     *
     * @param  string $type    异常类型
     * @param  string $message 自定义消息
     * @param  array  $headers 头信息
     * @return void
     */
    function _error($type, $message = '', array $headers = [])
    {
        $code = [
            'create_fail'     => 400,
            'update_fail'     => 400,
            'delete_fail'     => 400,
            'unauthorized'    => 401, // 表示用户没有权限（令牌、用户名、密码错误）
            'forbidden'       => 403, // 表示用户得到授权（与401错误相对），但是访问是被禁止的
            'not_found'       => 404,
            'validation_fail' => 422, // 验证错误
            'sql_fail'        => 500, // 数据库相关错误
        ][$type];

        if ($code === 422 && is_array($message)) {
            $errors = $message;
            throw new ValidationHttpException($errors);
        }

        abort($code, $message, $headers);
    }
}

if (!function_exists('_success')) {
    /**
     * 构造并返回请求成功的资源响应
     *
     * @param  string|array $data    自定义消息 或 资源数组
     * @param  array  $meta          额外信息
     * @param  array  $headers       头信息
     * @return void
     */
    function _success($data = null, array $meta = [], array $headers = [])
    {
        $message = '';
        $resource = [];
        $status_code = 200;

        // 消息通知
        if (is_null($data)) {
            $message = '';
        } else if (is_string($data)) {
            $message = $data;
        }
        // 分页资源
        else if (isset($data['current_page'])) {
            $resource = $data['data'];
            $meta = [
                'current_page' => $data['current_page'],
                'last_page' => $data['last_page'],
                'per_page' => $data['per_page'],
                'total' => $data['total'],
            ];
        }
        // 常规资源
        else {
            $resource = $data;
        }

        $content = compact('message', 'status_code', 'resource', 'meta');
        response($content, $status_code, $headers)->throwResponse();
    }
}

if (! function_exists('mix_mobile')) {
    /**
     * 混淆手机号
     * 
     * @param  string $mobile    原始手机号
     * @param  int    $startlen  开始长度
     * @param  int    $endlen    结束长度
     * 
     * @return string
     */
    function mix_mobile(string $mobile, int $startlen = 3, int $endlen = 4)
    {
        return mix_string($mobile, $startlen, $endlen);
    }
}

if (! function_exists('mix_string')) {
    /**
     * 混淆字符串
     *
     * @param  string $str       字符串
     * @param  int    $startlen  开始长度
     * @param  int    $endlen    结束长度
     * 
     * @return string
     */
    function mix_string(string $str, int $startlen, int $endlen)
    {
        $repstr = "";
        if (strlen($str) < ($startlen + $endlen + 1)) {
            return $str;
        }
        $count = strlen($str) - $startlen - $endlen;
        for ($i = 0; $i < $count; $i++) {
            $repstr .= "*";
        }
        return preg_replace('/(\d{' . $startlen . '})\d+(\d{' . $endlen . '})/', '${1}' . $repstr . '${2}', $str);
    }
}

if (!function_exists('array_to_string')) {
    /**
     * 数组转字符串（Migration 中构造注释）
     * @param  array $arr
     * @return string
     */
    function array_to_string(array $arr)
    {
        $str = '';
        foreach ($arr as $key => $value) {
            $str .= $key . '、' . $value . ' ';
        }
        return $str;
    }
}

if (! function_exists('number_format_floor')) {
    /**
     * 数字格式转换
     * @param  float $number
     * 
     * @return float
     */
    function number_format_floor($number)
    {
        return sprintf('%.10f', $number);
    }
}

if (!function_exists('trading_number')) {
    /**
     * 数组加密编码，输出字符串（用于生成交易号）时间戳
     * @param  string  $value
     * @param  int     $limit
     * @return string
     */
    function trading_number($timestamp = '', $limit = 18)
    {
        $str = '';
        $timestamp = $timestamp ?: time();
        $str .= date('YmdHis', $timestamp);
        $timestampArr = str_split($timestamp);
        shuffle($timestampArr);
        $length = strlen($timestamp);
        $str .= implode('', array_slice($timestampArr, 0, $length));
        return rtrim(mb_substr($str, 0, $limit, 'UTF-8'));
    }
}

if (!function_exists('d')) {
    /**
     * Dump the passed variables and end the script.
     *
     * @param  mixed
     * @return void
     */
    function d(...$args)
    {
        $backtrace = debug_backtrace();
        $file = $backtrace[0]['file'] . ':' . $backtrace[0]['line'];
        (new Dumper)->dump($file);
        foreach ($args as $x) {
            (new Dumper)->dump($x);
        }
        die;
    }
}

if (!function_exists('d_')) {
    /**
     * Dump the passed variables and end the script.
     *
     * @param  mixed
     * @return void
     */
    function d_()
    {
        $backtrace = debug_backtrace();
        Log::debug(var_export($backtrace[0], true));
    }
}

if (!function_exists('throw_exception')) {
    /**
     * Dump the passed variables and end the script.
     *
     * @param  mixed
     * @return void
     */
    function throw_exception($namespace, $exceptionClassName, $message = '', $debugMessage = null)
    {
        $namespace = $namespace . '\\Exceptions';
        if (!class_exists('\\' . $namespace . '\Exception')) {
            eval('namespace ' . $namespace . ' { class Exception extends \Api\ExtException {} }');
        }
        if (!class_exists('\\' . $namespace . '\\' . $exceptionClassName)) {
            eval('namespace ' . $namespace . ' { class ' . $exceptionClassName . ' extends Exception {} }');
        }
        eval('namespace ' . $namespace . ' { throw new ' . $exceptionClassName . '("' . $message . '", "' . $debugMessage . '"); }');
    }
}

if (! function_exists('cast_type')) {
    /**
     * 简单的类型转换
     * Cast an value to a native PHP type.
     * 支持的格式：int, float, string, boolean
     *
     * @param  string $type
     * @param  string $value
     * @return mixed
     */
    function cast_type($type, $value)
    {
        if (is_null($value)) {
            return null;
        }
        else {
            switch ($type) {
                case 'int':
                    return (int) $value;
                case 'float':
                    return (float) $value;
                case 'string':
                    return (string) $value;
                case 'boolean':
                    return (bool) $value;
                default:
                    return $value;
            }
        }
    }
}

if (!function_exists('get_guid')) {
    /**
     * 生成唯一的ID
     * @return string $uuid 返回的唯一ID
     */
    function get_guid($index = 0, $length = 13)
    {
        $uniqid = uniqid(md5(microtime(true)), true);
        $uuid = strtoupper(md5($uniqid));
        $return = substr(md5($uuid), $index, $length);
        return $return;
    }
}

if (! function_exists('generate_uuid')) {
    /**
     * 生成唯一的uuid
     * @return string $uuid 返回的唯uuid
     */
    function generate_uuid()
    {
        $charId = md5(uniqid(rand(), true));
        $hyphen = chr(45);
        $uuid = substr($charId, 0, 8).$hyphen
            .substr($charId, 8, 4).$hyphen
            .substr($charId, 12, 4).$hyphen
            .substr($charId, 16, 4).$hyphen
            .substr($charId, 20, 12);
        return $uuid;
    }
}

if (!function_exists('month_format_time')) {
    /**
     * 月份时间格式转换
     * @return string $time 日期时间
     */
    function month_format_time($time = null, $lang = 'en')
    {
        $time = $time ? : date('Y-m-d H:i:s');
        if ($lang == 'zh') {
            $month = date('Y年m月', strtotime($time));
            $return = ($month == date('Y年m月')) ? '本月' : $month;
        } else {
            $month = date('Y-m', strtotime($time));
            $return = ($month == date('Y-m')) ? 'This Month' : $month;
        }
        return $return;
    }
}

// 字符串截取，支持中文和其他编码
if (!function_exists('msubstr')) {

    function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
    {
        if (function_exists("mb_substr")) {
            $slice = mb_substr($str, $start, $length, $charset);
        } elseif (function_exists('iconv_substr')) {
            $slice = iconv_substr($str, $start, $length, $charset);
            if (false === $slice) {
                $slice = '';
            }
        } else {
            $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
            $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
            $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
            $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
            preg_match_all($re[$charset], $str, $match);
            $slice = join("", array_slice($match[0], $start, $length));
        }
        return $suffix ? $slice . '...' : $slice;
    }

}

/**
 * 高精度两个数相乘
 * @param $num1
 * @param $num2
 * @param int $decimals
 * @return string
 */
if (!function_exists('precision_mul')) {
    function precision_mul($num1, $num2, $decimals = 5) {
        return bcmul(number_format($num1, $decimals, '.', ''), number_format($num2, $decimals, '.', ''), $decimals);
    }
}

/**
 * 高精度两个数相除
 * @param $num1
 * @param $num2
 * @param int $decimals
 * @return string
 */
if (!function_exists('precision_div')) {
    function precision_div($num1, $num2, $decimals = 5) {
        return bcdiv(number_format($num1, $decimals, '.', ''), number_format($num2, $decimals, '.', ''), $decimals);
    }
}

/**
 * 高精度两个数相加
 * @param $num1
 * @param $num2
 * @param int $decimals
 * @return string
 */
if (!function_exists('precision_add')) {
    function precision_add($num1, $num2, $decimals = 5) {
        return bcadd(number_format($num1, $decimals, '.', ''), number_format($num2, $decimals, '.', ''), $decimals);
    }
}

/**
 * 高精度两个数相减
 * @param $num1
 * @param $num2
 * @param int $decimals
 * @return string
 */
if (!function_exists('precision_sub')) {
    function precision_sub($num1, $num2, $decimals = 5) {
        return bcsub(number_format($num1, $decimals, '.', ''), number_format($num2, $decimals, '.', ''), $decimals);
    }
}

if (! function_exists('trans')) {
    /**
     * 语言包翻译
     *
     * @param string $id
     * @param array  $replace
     * @param string $locale
     *
     * @return \Illuminate\Contracts\Translation\Translator|string
     */
    function trans($id = null, $replace = [], $locale = null)
    {
        if (is_null($id)) {
            return app('translator');
        }

        return app('translator')->trans($id, $replace, $locale);
    }
}

if (!function_exists('trans_choice')) {
    /**
     * Translates the given message based on a count.
     *
     * @param string               $id
     * @param int|array|\Countable $number
     * @param array                $replace
     * @param string               $locale
     *
     * @return string
     */
    function trans_choice($id, $number, array $replace = [], $locale = null)
    {
        return app('translator')->transChoice($id, $number, $replace, $locale);
    }
}

if (!function_exists('array_sequence')) {

    /**
     * 二维数组根据字段进行排序
     * @params array $array 需要排序的数组
     * @params string $field 排序的字段
     * @params string $sort 排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
     */

    function array_sequence($array, $field, $sort = 'SORT_DESC')
    {
        $arrSort = array();
        foreach ($array as $uniqid => $row) {
            foreach ($row as $key => $value) {
                $arrSort[$key][$uniqid] = $value;
            }
        }
        array_multisort($arrSort[$field], constant($sort), $array);
        return $array;
    }

}

if (!function_exists('arr_search')) {

    /**
     * 二维数组根据关键字模糊搜索
     * @params array $array 数组
     * @params string $keywords 模糊搜索关键词
     * @params array $type 需要搜索的字段
     */

    function arr_search($arrs, $keywords = null, $type = ['key'])
    {
        $result = [];
        foreach ($arrs as $key => $searchData) {
            $arr = [];
            foreach ($searchData as $k => $v) {
                for ($i = 0; $i < count($type); $i++) {
                    if ($k == $type[$i]) {
                        array_push($arr, $k);
                    }
                }
            }
            for ($a = 0; $a < count($arr); $a++) {
                if (strpos(strtoupper($searchData[$arr[$a]]), strtoupper($keywords)) !== false) {
                    $result[] = $searchData;
                }
            }
        }
        return $result;
    }
}

if (!function_exists('module_operation')) {
    /**
     * 取模计算
     *
     * @param float               $number
     * @param float               $divisor
     *
     * @return string
     */
    function module_operation($number, $divisor)
    {
        return fmod(floatval($number * 100), $divisor * 100);
    }
}

